package com.fcscs.cservice.domain;

import java.util.Comparator;
import java.util.List;

import com.fcscs.core.domain.HistoricalEntity;
import com.fcscs.cservice.common.CServiceCommonEnums.EditableCategoryEnum;
import com.fcscs.cservice.common.CServiceCommonEnums.EditableFieldEnum;
import com.fcscs.cservice.common.CServiceConstants;

public class FieldEditability extends HistoricalEntity {

	private static final long serialVersionUID = 6185350216721441499L;
	
	private EditableCategoryEnum category;
	private EditableFieldEnum field;
	private boolean editable = CServiceConstants.DEFAULT_EDITABILITY;

	@Override
	public DBLoc getDBLoc() {
		return DBLoc.GUEST;
	}

	public FieldEditability() {
		
	}

	public FieldEditability(EditableCategoryEnum category, EditableFieldEnum field, boolean editable) {
		this();
		this.category = category;
		this.field = field;
		this.editable = editable;
	}

	public void setCategory(String category) {
		this.category = category == null ? null : EditableCategoryEnum.valueOf(category);
	}

	public String getCategory() {
		return category == null ? null : category.toString();
	}

	public void setCategoryEnum(EditableCategoryEnum category) {
		this.category = category;
	}

	public EditableCategoryEnum getCategoryEnum() {
		return category;
	}

	public void setField(String field) {
		this.field = field == null ? null : EditableFieldEnum.valueOf(field);
	}

	public String getField() {
		return field == null ? null : field.toString();
	}

	public void setFieldEnum(EditableFieldEnum field) {
		this.field = field;
	}

	public EditableFieldEnum getFieldEnum() {
		return field;
	}

	public void setEditable(boolean editable) {
		this.editable = editable;
	}

	public boolean getEditable() {
		return editable;
	}

	public static class FieldEditabilityComparator implements Comparator<FieldEditability> {

		@Override
		public int compare(FieldEditability o1, FieldEditability o2) {
			int result = o1.getCategoryEnum().compareTo(o2.getCategoryEnum());
			result = result == 0 ? o1.getFieldEnum().compareTo(o2.getFieldEnum()) : result;
			return result;
		}
	}

	private static Comparator<FieldEditability> comparator = new FieldEditabilityComparator();
	

	public static Comparator<FieldEditability> getComparator() {
		return comparator;
	}

	/**
	 * the list should be sorted with FieldEditabilityComparator.comparator
	 * @param list
	 * @param category
	 * @param field
	 * @return
	 */
    public static int binarySearch(List<FieldEditability> list, EditableCategoryEnum category, EditableFieldEnum field) {
    	int low = 0;
    	int high = list.size()-1;

    	while (low <= high) {
    	    int mid = (low + high) >>> 1;
    	    FieldEditability midVal = list.get(mid);
    	    int cmp = midVal.getCategoryEnum().compareTo(category);
    	    cmp = cmp == 0 ? midVal.getFieldEnum().compareTo(field) : cmp;

    	    if (cmp < 0)
    		low = mid + 1;
    	    else if (cmp > 0)
    		high = mid - 1;
    	    else
    		return mid; // key found
    	}
    	return -(low + 1);  // key not found
    }

    @Override
    public String toString() {
    	return category.toString() + "-" + field.toString() + ":" + editable;
    }
}
